<?php

namespace App\Http\Services;


use App\Http\Model\AudioApi;
use App\Http\Model\Gift;
use App\Http\Model\Hint;
use App\Http\Model\NewYearGoods;
use App\Http\Model\Room;
use App\Http\Model\User;

class NewYearGoodsServices extends CommonServices
{
    private $userModel;
    private $audioModel;
    private $giftModel;
    private $roomModel;
    private $newYearGoods;
    private $redisLook = 'AWARD:ROOM:';
    private $bagTypeDiamond = [66000, 200000, 1000000];//礼包类型消耗钻石
    private $payBagTypeDiamond = [100, 200, 600];//礼包类型消耗钻石
    private $bagRadio = [0.5, 0.7, 0.9];//礼包收摊比例
    private $bagGiftId = [335, 343, 346];//用户塞入礼包大礼物id合集
    private $awardGiftId = [341, 345, 350];//用户塞入礼包补发礼物id合集
    private $endDateType = [
        [10, 20, 40],
        [20, 40, 60],
        [60, 80, 120],
    ];//用户塞入礼包大礼物id合集
    private $supplyBagGiftIds = [
        [336, 337, 338, 339, 340, 341],
        [342, 335, 344, 337, 338, 345],
        [347, 348, 342, 335, 336, 337, 340, 349, 350]
    ];//用户塞入礼包大礼物id合集
    private $supplyBagGiftNum = [
        [1, 1, 1, 1, 50, 50, 396],
        [1, 1, 1, 5, 8, 10, 474],
        [1, 2, 2, 2, 3, 3, 20, 20, 50, 397]
    ];
    const send_room_msg = ['我是欧皇 我为王', '老板，再来10000场', '我要拿大奖', '我相信，我可以', '给主持献上666', '主持你最美，但是奖励更美', '大奖对于我来说都是小问题', '不就是抽奖嘛，放着我来'];//房间内文案


    public function __construct()
    {
        $this->userModel = new User();
        $this->audioModel = new AudioApi();
        $this->giftModel = new Gift();
        $this->roomModel = new Room();
        $this->newYearGoods = new NewYearGoods();
    }


    /*
     * 创建礼包
     * @param $user_id 用户id
     * @param $room_id 房间id
     * @param $type 开启类型 0 1 2
     * @param $end_date 结束时间
     * @param $ratio 开启比例
     * @param $gift_id 礼物id
     * */
    public function createBag($user_id, $room_id, $type, $end_date, $ratio, $gift_id)
    {
//        $a = [16, 18, 19, 20, 21, 22, 23, 24];
//        $b = [58, 59, 60, 61, 62];
//        $room_id = $a[rand(0, 7)];
//        $user_id = $b[rand(0, 4)];
        $status = [
            'code' => 0,
            'msg' => '成功',
            'data' => '',
        ];
        do {
            if (!$room_id || !$user_id) {
                $status = [
                    'code' => 3002,
                    'msg' => '参数错误~',
                    'data' => ''
                ];
                break;
            }
            $lookKey = $this->redisLook . $room_id;
            if (check_redis_lock($lookKey)) {
                $status = [
                    'code' => 3002,
                    'msg' => '开奖中~ 请稍后开启礼包',
                    'data' => ''
                ];
                break;
            }
            $endTypeTimes = $this->endDateType[$type];
            $endTimes = $endTypeTimes[$end_date] * 60;
            $diamond = $this->bagTypeDiamond[$type];

            $openLog = $this->newYearGoods->getBagRoomType($room_id);
            if ($openLog) {
                //单房间开启单次
                $status = [
                    'code' => 3002,
                    'msg' => '该房间已开启年货礼包~',
                    'data' => ''
                ];
                break;
            }

            //用户支付钻石
            $payDiamondRes = $this->audioModel->diamond_recharge($user_id, $diamond, 6, $room_id);
            if ($payDiamondRes['code'] != 0) {
                $status = [
                    'code' => $payDiamondRes['code'],
                    'msg' => $payDiamondRes['msg'],
                    'data' => ''
                ];
                break;
            }
            if ($gift_id != 0) {
                $gift_id = $this->bagGiftId[$type];
            }
            //创建奖池
            $surplusNum = $this->supplyBagGiftNum[$type]; //奖池礼物总数量
            $surplusGiftId = $this->supplyBagGiftIds[$type]; //补充礼物id
            $numRadio = intval($this->bagRadio[$ratio] * array_sum($surplusNum));//开奖数量
            $this->newYearGoods->createPond($room_id, $gift_id, $surplusGiftId, $surplusNum, $numRadio);
            //生成房间礼包相关
            $score = time() + $endTimes;
            $this->newYearGoods->createRoomBagZADD($room_id, $score); //加入延时队列
            $this->newYearGoods->insertBagToRoom($room_id, $type, $diamond, $numRadio, $endTimes, $user_id); //房间开启礼包
            $roomInfo = $this->roomModel->getRoomInfoToRoomIdCacheToArr($room_id);
            $msg = $roomInfo['room_uid'] . '厅开始卖年货啦~——我要参与；';
            $this->audioModel->sendAllAppApi($user_id, $room_id, $msg);
            $msgStatus = [
                'code' => '0',
                'msg' => '发起成功',
                'activity_type' => 1,
                'room_id' => $room_id,
                'user_id' => $user_id
            ];
            $this->audioModel->openHtmlRoom($msgStatus);
        } while (false);
        return $status;
    }


    //用户参与年货
    public function partakeBag($user_id, $room_id)
    {
        do {
            if (!$room_id || !$user_id) {
                $status = [
                    'code' => 3002,
                    'msg' => '参数错误~',
                    'data' => ''
                ];
                break;
            }
            $lookKey = $this->redisLook . $room_id;
            if (check_redis_lock($lookKey)) {
                $status = [
                    'code' => 3002,
                    'msg' => '开奖中~ 请等待开奖',
                    'data' => ''
                ];
                break;
            }
            //查看房间是否开启
            $openType = $this->newYearGoods->getBagRoomType($room_id);
            if (!$openType || count($openType) != 6) {
                //未开启
                $status = [
                    'code' => 3002,
                    'msg' => '该房间未开启年货礼包~',
                    'data' => ''
                ];
                break;
            }
            if ($openType['endTimes'] < time()) {
                $status = [
                    'code' => 3002,
                    'msg' => '礼包到期~请等待开奖',
                    'data' => '',
                ];
                break;
            }
            $redisKeyLock = 'CACHE:PARTAKE' . $user_id . $room_id;
            if (redis_lock($redisKeyLock, 2) == false) {
                $status = [
                    'code' => 3002,
                    'msg' => '手速太快啦~',
                    'data' => ''
                ];
                break;
            }
            //库存
            $surplus = $this->newYearGoods->popConsumerPond($room_id);
            if (is_null($surplus)) {
                $status = [
                    'code' => 3002,
                    'msg' => '库存不足~请等待下次参与',
                    'data' => '',
                ];
                break;
            }
            //扣除用户钻石
            $type = $openType['type'];
            $diamond = $this->payBagTypeDiamond[$type];
            $payDiamond = $this->audioModel->diamond_recharge($user_id, $diamond, 5, $room_id);
            if ($payDiamond['code'] != 0) {
                //将礼物塞回奖池
                $status = [
                    'code' => $payDiamond['code'],
                    'msg' => $payDiamond['msg'],
                    'data' => ''
                ];
                $this->newYearGoods->pushConsumerPond($room_id, $surplus); //库存+1
                break;
            }
            //用户参与记录
            $partakeLog = $this->newYearGoods->getUserPartakeLog($user_id);
            $logKey = $room_id . '-' . $type . '-0'; //房间-类型-状态
            if (!in_array($logKey, $partakeLog)) {
                //首次参加
                $this->newYearGoods->createUserPartakeLog($user_id, $room_id, $type);
            }
            //添加用户参与记录
            $this->newYearGoods->pushPartakeToRoom($room_id, $user_id);
            $len = $this->newYearGoods->decBagRoomInfo($room_id, 'surplus', '-1'); //库存-1
            //剩余数量为 0 修改礼包开奖时间
            if ($len == 0) {
                $time = time() + 5;
                $this->newYearGoods->createRoomBagZADD($room_id, $time);
                //礼包信息进入开奖
                $endTime = $time - $openType['endTimes'];
                $this->newYearGoods->decBagRoomInfo($room_id, 'endTimes', $endTime);
            }
            $status = [
                'code' => 0,
                'msg' => '成功~',
                'data' => ''
            ];
            redis_unlock($redisKeyLock);
        } while (false);
        return $status;
    }

    //延时队列发放奖励
    public function awardScoreList()
    {
        do {
            //获取礼包可开奖房间
            $room_ids = $this->newYearGoods->getEndDateRoomIds();
            if (!$room_ids) {
                break;
            }
            //发放1个房间
            $room_ids = array_keys($room_ids);
            $room_ids = array_slice($room_ids, 0, 1);
            foreach ($room_ids as $room_id) {
                $redisKeyLock = $this->redisLook . $room_id;
                //加入房间锁
                if (redis_lock($redisKeyLock, 10) == false) {
                    //开奖中房间 轮空
                    break;
                }
                $this->newYearGoods->delRoomScore($room_id);//删除房间延时队列
                $bagInfo = $this->newYearGoods->getBagRoomType($room_id);
                if (count($bagInfo) != 6) {
                    //删除房间开启信息
                    $this->newYearGoods->delBagRoomType($room_id);
                    //删除用户参与记录
                    $this->newYearGoods->delPartakeLog($room_id);
                    $this->newYearGoods->delPond($room_id);
                    $this->newYearGoods->delConsumerPond($room_id);
                    break;
                }
                $type = $bagInfo['type'];
                //获取参与用户
                $partakeUser = $this->newYearGoods->getRoomPartakeUser($room_id);
                $giftPrice = 0;
                $len = count($partakeUser);
                $profit = $len * $this->payBagTypeDiamond[$type];
                $pond = $this->newYearGoods->getPondLen($room_id);
                while ($len > 0) {
                    $userId = $this->newYearGoods->popPartakeToRoom($room_id);
                    $giftId = $this->newYearGoods->popPond($room_id);
                    write_log('awardGiftLog', '礼物', ['user_id' => $userId, 'gift_id' => $giftId, 'room_id' => $room_id, 'len' => count($partakeUser), 'pond' => $pond]);
                    if (is_null($giftId)) {
//                    //超出礼物
//                    $gift = $this->giftModel->getGiftInfoCacheToArr($giftIdNull);
//                    $nullGiftPrice = $nullGiftPrice + $gift['price']; //多余扣除
//                    $this->audioModel->sendGift($vv, $giftIdNull, 18, 1);
                        write_log('awardGiftErrorLog', '礼物库存不足导致', ['user_id' => $userId, 'room_id' => $room_id, 'len' => count($partakeUser), 'pond' => $pond]);
                        continue;
                    }
                    //获取礼物信息
                    $giftInfo = $this->giftModel->getGiftInfoCacheToArr($giftId);
                    //用户获奖记录
                    $this->newYearGoods->createAwardLog($userId, $giftId, $bagInfo['type']);
                    //发放礼物
                    $this->audioModel->sendGift($userId, $giftId, 18, 1);
                    //支出礼物价值
                    $giftPrice = $giftPrice + $giftInfo['price'];
                    //大礼物飘屏
                    if ($giftId == $this->bagGiftId[$type]) {
                        $userInfo = $this->userModel->getUserInfoToCache($userId);
                        $msg = '恭喜' . $userInfo['nickname'] . '开出' . $giftInfo['name'] . '——我也想要；';
                        $this->audioModel->sendAllAppApi($userId, $room_id, $msg);
                    }
                    $len--;
                }
                $partakeUserId = array_unique($partakeUser);
                $roomCache = $this->roomModel->getRoomInfoToRoomIdCacheToArr($room_id);
                foreach ($partakeUserId as $k => $v) {
                    //修改用户参与记录中的开启状态
                    $k1 = $room_id . '-' . $type . '-0';
                    $k2 = $room_id . '-' . $type . '-1';
                    $this->newYearGoods->updateUserPartakeLog($v, $k1, $k2);
                    $msg = '您在房间' . $roomCache['room_uid'] . '参与的年货礼包获得礼物已到账，请立即查收哟~';
                    $this->audioModel->sendMsgApi($v, $msg);
                }
                //返回开启者收益
                $profitDiamond = $bagInfo['diamond'] - $giftPrice + $profit; //总钻石 - 多余支出礼物 - 总支出礼物 + 用户参与 = 开启收益
                $this->audioModel->diamond_recharge($bagInfo['user_id'], $profitDiamond, 7, $room_id);//开启者返还总收益钻石

                //生成房间收益记录
                $this->newYearGoods->createRoomProfitLog($room_id, $profitDiamond, $bagInfo['type']);
                //删除房间开启信息
                $this->newYearGoods->delBagRoomType($room_id);
                //删除用户参与记录
                $this->newYearGoods->delPartakeLog($room_id);
                $this->newYearGoods->delPond($room_id);
                $this->newYearGoods->delConsumerPond($room_id);
                //解锁
                redis_unlock($redisKeyLock);
                break;
            }
        } while (false);
        return true;
    }

    //用户奖励记录
    public function getUserLog($user_id)
    {

        $log = $this->newYearGoods->getUserAwardLog($user_id);
        $log = array_reverse($log);
        $i = 0;
        $data = [];
        foreach ($log as $k => $v) {
            $key = explode('-', $k);
            $gift_info = $this->giftModel->getGiftInfoCacheToArr($key[0]);
            $data[$i] = [
                'name' => $gift_info['name'],
                'date' => date('m' . '月' . 'd' . '日', $key[1]),
                'type' => $v,
            ];
            $i++;
        }
        return $data;
    }

    //房间记录
    public function getRoomLog($room_id)
    {
        $log = $this->newYearGoods->getRoomOpenLog($room_id);
        $log = array_reverse($log);
        $i = 0;
        $data = [];
        foreach ($log as $k => $v) {
            $key = explode('-', $k);
            $data[$i] = [
                'profit' => $v,
                'date' => date('m' . '月' . 'd' . '日', $key[1]),
                'type' => $key[0],
            ];
            $i++;
        }
        return $data;
    }

    //房间礼包信息
    public function getOpenInfo($room_id)
    {
        $data = [
            'roomName' => '',//0 秒 1分
            'endDateType' => 0,//0 秒 1分
            'bagType' => 3,//礼包等级
            'surplusTime' => [0, 0],//剩余时间
            'time' => 0,//剩余时间
        ];
        do {
            if (!$room_id) {
                break;
            }
            //房间信息
            $roomInfo = $this->roomModel->getRoomInfoToRoomIdCacheToArr($room_id);
            if (!$roomInfo) {
                break;
            }
            $data['roomName'] = mb_substr($roomInfo['name'], 0, 6, 'utf-8');;
            $openType = $this->newYearGoods->getBagRoomType($room_id);
            if (count($openType) != 6) {
                $this->newYearGoods->delBagRoomType($room_id); //删除开启信息
                $this->newYearGoods->delRoomScore($room_id);//删除掩饰队列
                $this->newYearGoods->delPond($room_id);//删除池子
                break;
            }
            if (!$openType) {
                break;
            }

            $type = $openType['type'];
            //查看剩余时间
            $score = $this->newYearGoods->getRoomScore($room_id);
            $surplusTime = $score - time();
            $data['time'] = $surplusTime;

            $endDate = intval($surplusTime / 60);
            if ($endDate > 0) {
                $data['endDateType'] = 1;
                $surplusTime = str_split($endDate, 1);
            } else {
                $surplusTime = str_split($surplusTime, 1);
            }
            $data['bagType'] = $type;
            $data['surplusTime'] = $surplusTime;
        } while (false);
        return $data;
    }

    public function getUserPartakeInfo($user_id)
    {
        $data = [
            'userInfo' => [],
            'partakeLog' => '',
        ];
        do {
            $userInfo = $this->userModel->getUserInfoToCache($user_id);
            $log = $this->newYearGoods->getUserPartakeLog($user_id);
            $logArr = [];
            $i = 0;
            foreach ($log as $v) {
                $key = explode('-', $v);
                $roomInfo = $this->roomModel->getRoomInfoToRoomIdCacheToArr($key[0]);
                $logArr[$i]['room_uid'] = $roomInfo['room_uid'];
                $logArr[$i]['type'] = $key[1];
                $logArr[$i]['status'] = $key[2];
                $i++;
            }

            $data['userInfo'] = $userInfo;
            $data['partakeLog'] = $logArr;
        } while (false);
        return $data;
    }


    //获取开启礼包房间
    public function getOpenBagRoom()
    {
        $roomIds = $this->newYearGoods->getEndDateRoomIds();
        $roomIds = array_keys($roomIds);
        if (!$roomIds) {
            //为空 获取当前开启房间
            $room = $this->audioModel->getOpenRoomId();
            $roomIds = $room['data']['list'];
        }
        $data['room_id'] = $roomIds[array_rand($roomIds, 1)];
        return $data;
    }

    //发放礼包奖品
    public function awardGift($room_id)
    {
        do {
            $redisKeyLock = $this->redisLook . $room_id;
            //加入房间锁
            if (redis_lock($redisKeyLock, 10) == false) {
                //开奖中房间 轮空
                break;
            }
            $bagInfo = $this->newYearGoods->getBagRoomType($room_id);
            if (count($bagInfo) != 6) {
                //删除房间开启信息
                $this->newYearGoods->delBagRoomType($room_id);
                //删除用户参与记录
                $this->newYearGoods->delPartakeLog($room_id);
                $this->newYearGoods->delPond($room_id);
                $this->newYearGoods->delConsumerPond($room_id);
                break;
            }

            $type = $bagInfo['type'];
            //获取参与用户
            $partakeUser = $this->newYearGoods->getRoomPartakeUser($room_id);
            $giftPrice = 0;
            $len = count($partakeUser);
            $profit = $len * $this->payBagTypeDiamond[$type];

            while ($len > 0) {
                $userId = $this->newYearGoods->popPartakeToRoom($room_id);
                $giftId = $this->newYearGoods->popPond($room_id);
                if (is_null($giftId)) {
//                    //超出礼物
//                    $gift = $this->giftModel->getGiftInfoCacheToArr($giftIdNull);
//                    $nullGiftPrice = $nullGiftPrice + $gift['price']; //多余扣除
//                    $this->audioModel->sendGift($vv, $giftIdNull, 18, 1);
                    write_log('awardGiftErrorLog', '礼物库存不足导致', ['user_id' => $userId, 'room_id' => $room_id]);
                    continue;
                }
                //获取礼物信息
                $giftInfo = $this->giftModel->getGiftInfoCacheToArr($giftId);
                //用户获奖记录
                $this->newYearGoods->createAwardLog($userId, $giftId, $bagInfo['type']);
                //发放礼物
                $this->audioModel->sendGift($userId, $giftId, 18, 1);
                //支出礼物价值
                $giftPrice = $giftPrice + $giftInfo['price'];
                //大礼物飘屏
                if ($giftId == $this->bagGiftId[$type]) {
                    $userInfo = $this->userModel->getUserInfoToCache($userId);
                    $msg = '恭喜' . $userInfo['nickname'] . '开出' . $giftInfo['name'] . '——我也想要；';
                    $this->audioModel->sendAllAppApi($userId, $room_id, $msg);
                }
                $len--;
            }
            $partakeUserId = array_unique($partakeUser);
            $roomCache = $this->roomModel->getRoomInfoToRoomIdCacheToArr($room_id);
            foreach ($partakeUserId as $k => $v) {
                //修改用户参与记录中的开启状态
                $k1 = $room_id . '-' . $type . '-0';
                $k2 = $room_id . '-' . $type . '-1';
                $this->newYearGoods->updateUserPartakeLog($v, $k1, $k2);
                $msg = '您在房间' . $roomCache['room_uid'] . '参与的年货礼包获得礼物已到账，请立即查收哟~';
                $this->audioModel->sendMsgApi($v, $msg);
            }
            //返回开启者收益
            $profitDiamond = $bagInfo['diamond'] - $giftPrice + $profit; //总钻石 - 多余支出礼物 - 总支出礼物 + 用户参与 = 开启收益
            $this->audioModel->diamond_recharge($bagInfo['user_id'], $profitDiamond, 7, $room_id);//开启者返还总收益钻石

            //生成房间收益记录
            $this->newYearGoods->createRoomProfitLog($room_id, $profitDiamond, $bagInfo['type']);
            //删除房间开启信息
            $this->newYearGoods->delBagRoomType($room_id);
            //删除用户参与记录
            $this->newYearGoods->delPartakeLog($room_id);
            $this->newYearGoods->delPond($room_id);
            $this->newYearGoods->delConsumerPond($room_id);
            //解锁
            redis_unlock($redisKeyLock);
            break;
        } while (false);
    }

    public function getPond($is_gift, $type, $ratio, $diamond)
    {
        if ($is_gift != 0) {
            $is_gift = $this->bagGiftId[$type];
        }
        $room_id = 10 + $is_gift;
        //创建奖池
        $surplusNum = $this->supplyBagGiftNum[$type]; //奖池礼物总数量
        $surplusGiftId = $this->supplyBagGiftIds[$type]; //补充礼物id
        $numRadio = intval($this->bagRadio[$ratio] * array_sum($surplusNum));//开奖数量
        $this->newYearGoods->createPond($room_id, $is_gift, $surplusGiftId, $surplusNum, $numRadio);
        $giftPrice = 0;
        echo '礼物总数量' . $numRadio;
        $allDiamond = $numRadio * $diamond;
        $giftArr = [];
        while ($numRadio > 0) {
            $giftId = $this->newYearGoods->popPond($room_id);
            $giftInfo = $this->giftModel->getGiftInfoCacheToArr($giftId);
            //支出礼物价值
            $giftPrice = $giftPrice + $giftInfo['price'];
            if ($giftId == $this->bagGiftId[$type]) {
                echo '<br/>';
                echo '大礼物' . $giftInfo['name'];
            }
            $giftArr[] = $giftInfo['name'];
            $numRadio--;
        };
        $this->newYearGoods->delPond($room_id);

        echo '<br/>';
        echo '用户支付钻石' . $allDiamond;
        echo '<br/>';
        echo '支出礼物价值' . $giftPrice;
        echo '<br/>';
        echo '开启扣费' . $this->bagTypeDiamond[$type];
        echo '<br/>';
        $profit = $this->bagTypeDiamond[$type] - $giftPrice + $allDiamond;
        echo '收益' . $profit;
        echo '<br/>';
        $di = 0;
        if ($profit >= $this->bagTypeDiamond[$type]) {
            $di = $profit - $this->bagTypeDiamond[$type];
            $this->newYearGoods->pondLog('add', $is_gift, $type, $di, $ratio);
        } else {
            $di = $this->bagTypeDiamond[$type] - $profit;
            $this->newYearGoods->pondLog('reduce', $is_gift, $type, $di, $ratio);
        }
        echo '产出礼物对应数量';
        dump(array_count_values($giftArr));
        $log = $this->newYearGoods->getPondLog($is_gift, $type, $ratio);
        dump($log);
    }


}